<template>
	<view class="spc-xr-chart">
		<!-- 均值图 -->
		<view class="x-f">
			<view style="transform: rotate(-90deg);font-size: 12px;">
				<text>平均值</text>
			</view>

			<qiun-data-charts ref="meanChart" type="line" :opts="meanChartOpts" :ontouch="true" onzoom
				:chartData="meanChartData" @getIndex="onMeanChartIndex"></qiun-data-charts>
		</view>


		<!-- 极差图 -->

		<view class="x-f">
			<view style="transform: rotate(-90deg);font-size: 12px;">
				<text>极差值</text>
			</view>
			<qiun-data-charts style="margin-top: 20px;" ref="rangeChart" type="line" :opts="rangeChartOpts"
				:ontouch="true" onzoom :chartData="rangeChartData" @getIndex="onRangeChartIndex"></qiun-data-charts>
		</view>
	</view>
</template>

<script>
	export default {
		name: "SpcXRChart",
		props: {
			data: {
				type: Array,
				required: true
			},
			spec: {
				type: Object,
				default: () => ({
					usl: null,
					lsl: null,
					target: null
				})
			}
		},
		data() {
			return {
				meanChartData: {},
				rangeChartData: {},
				meanChartOpts: {
					legend: {},
					xAxis: {
						disableGrid: true
					},
					yAxis: {},
					extra: {
						line: {
							type: "straight",
							animation: true,
							disableLegend: false
						},
						markLine: {
							data: []
						}
					}
				},
				rangeChartOpts: {
					legend: {},
					xAxis: {
						disableGrid: true
					},
					yAxis: {},
					extra: {
						line: {
							type: "straight",
							animation: true,
							disableLegend: false
						},
						markLine: {
							data: []
						}
					}
				}
			};
		},
		mounted() {
			this.processData(this.data)
		},
		methods: {
			processData(data) {
				if (!data || data.length === 0) return;

				const xLabels = data.map((item, index) => index + 1);
				const meanValues = data.map(item => item.mean);
				const rangeValues = data.map(item => item.range);

				// 1. 计算控制限
				const meanControlLimits = this.calculateControlLimits(meanValues);
				const rangeControlLimits = this.calculateRangeControlLimits(rangeValues);

				// 2. 计算均值图Y轴范围（使用USL、CL为基准，数据超限时用极端值）
				const meanYAxisOptions = this.calculateMeanYAxisOptions(meanValues, this.spec, meanControlLimits);

				// 3. 计算极差图Y轴范围（使用UCL、LCL为基准，数据超限时用极端值）
				const rangeYAxisOptions = this.calculateRangeYAxisOptions(rangeValues, rangeControlLimits);

				// 4. 构建均值图数据
				this.meanChartData = {
					categories: xLabels,
					series: [{
						name: "均值",
						data: meanValues,
						color: "#1890FF"
					}]
				};

				// 5. 配置均值图标记线
				const meanMarkLines = [{
						value: meanControlLimits.ucl.toFixed(3),
						labelText: 'UCL=' + meanControlLimits.ucl.toFixed(3),
						showLabel: true,
						labelAlign: 'right',
						lineColor: '#f56c6c',
						labelFontColor: '#f56c6c',
						labelBgOpacity: 0
					},
					{
						value: meanControlLimits.cl.toFixed(3),
						labelText: 'CL=' + meanControlLimits.cl.toFixed(3),
						showLabel: true,
						labelAlign: 'right',
						lineColor: '#f56c6c',
						labelFontColor: '#f56c6c',
						labelBgOpacity: 0
					},
					{
						value: meanControlLimits.lcl.toFixed(3),
						labelText: 'LCL=' + meanControlLimits.lcl.toFixed(3),
						showLabel: true,
						labelAlign: 'right',
						lineColor: '#f56c6c',
						labelFontColor: '#f56c6c',
						labelBgOpacity: 0
					}
				];

				if (this.spec.usl !== null) {
					meanMarkLines.push({
						labelText: 'USL=' + this.spec.usl.toFixed(3),
						value: this.spec.usl.toFixed(3),
						showLabel: true,
						labelAlign: 'right',
						lineColor: '#3fc314',
						labelFontColor: '#3fc314',
						labelBgOpacity: 0
					});
				}

				if (this.spec.lsl !== null) {
					meanMarkLines.push({
						labelText: 'LSL=' + this.spec.lsl.toFixed(3),
						value: this.spec.lsl.toFixed(3),
						showLabel: true,
						labelAlign: 'right',
						lineColor: '#3fc314',
						labelFontColor: '#3fc314',
						labelBgOpacity: 0
					});
				}

				if (this.spec.target !== null) {
					meanMarkLines.push({
						labelText: 'Target=' + this.spec.target.toFixed(3),
						value: this.spec.target.toFixed(3),
						showLabel: true,
						labelAlign: 'right',
						lineColor: '#3fc314',
						labelFontColor: '#3fc314',
						labelBgOpacity: 0
					});
				}

				// 更新均值图配置
				this.meanChartOpts = {
					padding: [20, 80, 0, 0],
					legend: {
						show: false
					},
					xAxis: {
						disableGrid: true
					},
					yAxis: meanYAxisOptions,
					extra: {
						line: {
							type: "straight",
							animation: true,
							disableLegend: false
						},
						markLine: {
							type: "dash",
							data: meanMarkLines
						}
					}
				};

				// 6. 构建极差图数据
				this.rangeChartData = {
					categories: xLabels,
					series: [{
						name: "极差",
						data: rangeValues,
						color: "#1890FF"
					}]
				};

				// 7. 配置极差图标记线
				this.rangeChartOpts = {
					padding: [20, 80, 0, 0],
					legend: {
						show: false
					},
					xAxis: {
						disableGrid: true
					},
					yAxis: rangeYAxisOptions,
					extra: {
						line: {
							type: "straight",
							animation: true,
							disableLegend: false
						},
						markLine: {
							type: 'dash',
							data: [{
									value: rangeControlLimits.ucl.toFixed(3),
									labelText: 'UCL=' + rangeControlLimits.ucl.toFixed(3),
									showLabel: true,
									labelAlign: 'right',
									lineColor: '#f56c6c',
									labelFontColor: '#f56c6c',
									labelBgOpacity: 0
								},
								{
									value: rangeControlLimits.cl.toFixed(3),
									labelText: 'CL=' + rangeControlLimits.cl.toFixed(3),
									showLabel: true,
									labelAlign: 'right',
									lineColor: '#f56c6c',
									labelFontColor: '#f56c6c',
									labelBgOpacity: 0
								},
								{
									value: Math.max(0, rangeControlLimits.lcl).toFixed(3),
									labelText: 'LCL=' + Math.max(0, rangeControlLimits.lcl).toFixed(3),
									showLabel: true,
									labelAlign: 'right',
									lineColor: '#f56c6c',
									labelFontColor: '#f56c6c',
									labelBgOpacity: 0
								}
							]
						}
					}
				};
			},

			calculateControlLimits(values) {
				const mean = values.reduce((sum, val) => sum + val, 0) / values.length;
				const stdDev = Math.sqrt(
					values.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / values.length
				);

				return {
					ucl: mean + 3 * stdDev,
					cl: mean,
					lcl: mean - 3 * stdDev
				};
			},

			calculateRangeControlLimits(rangeValues) {
				const mean = rangeValues.reduce((sum, val) => sum + val, 0) / rangeValues.length;
				const stdDev = Math.sqrt(
					rangeValues.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / rangeValues.length
				);

				return {
					ucl: mean + 3 * stdDev,
					cl: mean,
					lcl: Math.max(0, mean - 3 * stdDev)
				};
			},

			// 均值图Y轴范围计算：以USL、CL为基准，数据超限时用极端值
			calculateMeanYAxisOptions(values, spec, controlLimits) {
				// 获取数据的极端值
				const dataMax = Math.max(...values);
				const dataMin = Math.min(...values);

				// 初始边界值
				let yMax, yMin;

				// 优先使用USL作为上边界基准，若数据超出则使用数据最大值
				if (spec.usl !== null) {
					yMax = Math.max(spec.usl, dataMax);
				} else {
					// 没有USL时使用控制限的UCL作为基准
					yMax = Math.max(controlLimits.ucl, dataMax);
				}

				// 优先使用CL作为下边界基准，若数据超出则使用数据最小值
				yMin = Math.min(controlLimits.cl, dataMin);

				// 处理特殊情况：如果没有足够的数据范围，添加适当边距
				if (yMax <= yMin) {
					const defaultRange = 1; // 默认范围
					yMax = Math.max(yMax, dataMax + defaultRange / 2);
					yMin = Math.min(yMin, dataMin - defaultRange / 2);
				} else {
					// 添加5%的边距，避免数据贴边
					const padding = (yMax - yMin) * 0.05;
					yMax += padding;
					yMin -= padding;
				}

				return {
					format: val => val.toFixed(3),
					data: [{
						min: +yMin.toFixed(3),
						max: +yMax.toFixed(3),
						tofix: 2
					}]
				};
			},

			// 极差图Y轴范围计算：以UCL、LCL为基准，数据超限时用极端值
			calculateRangeYAxisOptions(values, controlLimits) {
				if (values.length === 0) return {
					data: [{
						min: 0,
						max: 1
					}]
				};

				// 获取数据的极端值
				const dataMax = Math.max(...values);
				const dataMin = Math.min(...values);

				// 上边界：取UCL和数据最大值中的较大者
				let yMax = Math.max(controlLimits.ucl, dataMax);

				// 下边界：取LCL和数据最小值中的较小者，且不小于0
				let yMin = Math.min(controlLimits.lcl, dataMin);
				yMin = Math.max(0, yMin); // 极差不能为负

				// 处理特殊情况：如果没有足够的数据范围，添加适当边距
				if (yMax <= yMin) {
					const defaultRange = 1; // 默认范围
					yMax = Math.max(yMax, dataMax + defaultRange / 2);
					yMin = Math.min(yMin, dataMin - defaultRange / 2);
					yMin = Math.max(0, yMin); // 确保不小于0
				} else {
					// 添加5%的边距，避免数据贴边
					const padding = (yMax - yMin) * 0.05;
					yMax += padding;
					if (yMin > 0) {
						yMin -= padding;
					}
				}

				return {
					format: val => val.toFixed(3),
					data: [{
						min: +yMin.toFixed(3),
						max: +yMax.toFixed(3),
						tofix: 2
					}]
				};
			},

			onMeanChartIndex(e) {
				const index = e.currentIndex.index;
			},
			onRangeChartIndex(e) {
				const index = e.currentIndex.index;
			}
		}
	};
</script>

<style scoped>
	.spc-xr-chart {
		display: flex;
		flex-direction: column;
		padding: 20rpx 20rpx 20rpx 0;
	}

	qiun-data-charts {
		margin-bottom: 40rpx;
		background: #fff;
		border-radius: 16rpx;
		box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.05);
	}
</style>